package com.tianletan.pool;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

/**
 * 采用动态代理实现对数据库连接的代理
 * */

public class ConnectionProxy implements InvocationHandler {

    // 被代理的真实连接
    private Connection realConnection;

    // 代理连接
    private Connection proxyConnection;

    private MyDataSource myDataSource;

    public Connection getRealConnection() {
        return realConnection;
    }

    public void setRealConnection(Connection realConnection) {
        this.realConnection = realConnection;
    }

    public Connection getProxyConnection() {
        return proxyConnection;
    }

    public void setProxyConnection(Connection proxyConnection) {
        this.proxyConnection = proxyConnection;
    }

    public MyDataSource getMyDataSource() {
        return myDataSource;
    }

    public void setMyDataSource(MyDataSource myDataSource) {
        this.myDataSource = myDataSource;
    }

    // 构造方法，通过 真实连接 和 数据源 生成 代理连接
    public ConnectionProxy(Connection realConnection, MyDataSource myDataSource) {
        this.realConnection = realConnection;
        this.myDataSource = myDataSource;
        // 生成代理连接
        this.proxyConnection = (Connection) Proxy.newProxyInstance(
                Connection.class.getClassLoader(),
                new Class<?>[] {Connection.class},
                this);
    }

    // 当调用connection对象里面的方法时，会应用此invoke方法里的增强
    // 只代理close方法（不关闭连接，放入pool中），其他方法不变
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 获取被代理对象被调用的方法名
        String methodName = method.getName();
        if(methodName.equalsIgnoreCase("close")){
            // 把连接归还给连接池pool
            myDataSource.closeConnection(this);


        }
        return method.invoke(realConnection, args);

    }
}
